package com.loren.oauth.config;

import com.loren.oauth.data.constant.DataConstant;
import com.loren.oauth.handler.CustomLoginFailureHandler;
import com.loren.oauth.handler.CustomLogoutSuccessHandler;
import com.loren.oauth.web.filter.UserAuthorizeFilter;
import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
@AllArgsConstructor
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class OAuthWebSecurityConfig extends WebSecurityConfigurerAdapter {

    private final UserDetailsService userDetailsService;

    private final CustomLoginFailureHandler customLoginFailureHandler;

    private final CustomLogoutSuccessHandler customLogoutSuccessHandler;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(this.userDetailsService).passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilterBefore(new UserAuthorizeFilter(), UsernamePasswordAuthenticationFilter.class)
                .formLogin().failureHandler(this.customLoginFailureHandler)
                .loginPage(DataConstant.AUTH_LOGIN_URL).loginProcessingUrl(DataConstant.AUTH_LOGIN_URL)
                .usernameParameter(DataConstant.USERNAME_PARAMETER).passwordParameter(DataConstant.PASSWORD_PARAMETER)
                .and()
                .logout().logoutUrl(DataConstant.AUTH_LOGOUT_URL).logoutSuccessHandler(this.customLogoutSuccessHandler)
                .and()
                .authorizeRequests().antMatchers(DataConstant.IGNORE_URL).permitAll()
                .anyRequest().authenticated()
                .and()
                .csrf().disable();
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}
